home *** CD-ROM | disk | FTP | other *** search
/ Aminet 44 / Aminet 44 (2001)(GTI - Schatztruhe)[!][Aug 2001].iso / Aminet / misc / emu / p-interp.lha / p-interp-0.4 / ptrace.c < prev    next >
C/C++ Source or Header  |  2001-06-06  |  16KB  |  775 lines

  1. /*
  2.  
  3.   P-Code interpreter (to run the apple pascal system)
  4.   Copyright (C) 2000 Mario Klebsch
  5.  
  6.   This program is free software; you can redistribute it and/or modify
  7.   it under the terms of the GNU General Public License as published by
  8.   the Free Software Foundation; either version 2 of the License, or
  9.   (at your option) any later version.
  10.  
  11.   This program is distributed in the hope that it will be useful,
  12.   but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.   GNU General Public License for more details.
  15.  
  16.   You should have received a copy of the GNU General Public License
  17.   along with this program; if not, write to the Free Software
  18.   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  19.  
  20.  
  21.   $Log: ptrace.c,v $
  22.   Revision 1.6  2001/06/06 23:00:27  mario
  23.   Anzahl der Elemente beim Compare von Byte- und Word-Arrays
  24.   ist B, nicht UB.
  25.  
  26.   Revision 1.5  2001/05/27 16:21:48  mario
  27.   - Neue Kommandozeilenoption zum Tracen einer einzigen Prozedur
  28.  
  29.   - Auch beim Disassemblieren  von Segment 0 werden jetzt die
  30.     korrekten Prozedurnamen angezeigt.
  31.  
  32.   Revision 1.4  2001/05/26 15:13:29  mario
  33.   Diverse kleine Fehler behoben, fehlende #includes, Labels ohne Statement
  34.   dahinter, ...
  35.  
  36.   Revision 1.3  2001/05/20 20:14:40  mario
  37.   Neues Gerät PRINTER: implementiert
  38.  
  39.   Revision 1.2  2001/05/20 13:12:02  mario
  40.   CVS-Idents und Logs eingefügt
  41.  
  42.  
  43. */
  44.  
  45. #ident "$Id: ptrace.c,v 1.6 2001/06/06 23:00:27 mario Exp $";
  46.  
  47. #include <stdio.h>
  48. #include <string.h>
  49.  
  50. #include "ptrace.h"
  51.  
  52. static const char *Instructions[256]= {
  53.   "sldc    0", 
  54.   "sldc    1", 
  55.   "sldc    2", 
  56.   "sldc    3", 
  57.   "sldc    4", 
  58.   "sldc    5", 
  59.   "sldc    6", 
  60.   "sldc    7", 
  61.   "sldc    8", 
  62.   "sldc    9", 
  63.   "sldc    10", 
  64.   "sldc    11", 
  65.   "sldc    12", 
  66.   "sldc    13", 
  67.   "sldc    14", 
  68.   "sldc    15", 
  69.   "sldc    16", 
  70.   "sldc    17", 
  71.   "sldc    18", 
  72.   "sldc    19", 
  73.   "sldc    20", 
  74.   "sldc    21", 
  75.   "sldc    22", 
  76.   "sldc    23", 
  77.   "sldc    24", 
  78.   "sldc    25", 
  79.   "sldc    26", 
  80.   "sldc    27", 
  81.   "sldc    28", 
  82.   "sldc    29", 
  83.   "sldc    30", 
  84.   "sldc    31", 
  85.   "sldc    32", 
  86.   "sldc    33", 
  87.   "sldc    34", 
  88.   "sldc    35", 
  89.   "sldc    36", 
  90.   "sldc    37", 
  91.   "sldc    38", 
  92.   "sldc    39", 
  93.   "sldc    40", 
  94.   "sldc    41", 
  95.   "sldc    42", 
  96.   "sldc    43", 
  97.   "sldc    44", 
  98.   "sldc    45", 
  99.   "sldc    46", 
  100.   "sldc    47", 
  101.   "sldc    48", 
  102.   "sldc    49", 
  103.   "sldc    50", 
  104.   "sldc    51", 
  105.   "sldc    52", 
  106.   "sldc    53", 
  107.   "sldc    54", 
  108.   "sldc    55", 
  109.   "sldc    56", 
  110.   "sldc    57", 
  111.   "sldc    58", 
  112.   "sldc    59", 
  113.   "sldc    60", 
  114.   "sldc    61", 
  115.   "sldc    62", 
  116.   "sldc    63", 
  117.   "sldc    64", 
  118.   "sldc    65", 
  119.   "sldc    66", 
  120.   "sldc    67", 
  121.   "sldc    68", 
  122.   "sldc    69", 
  123.   "sldc    70", 
  124.   "sldc    71", 
  125.   "sldc    72", 
  126.   "sldc    73", 
  127.   "sldc    74", 
  128.   "sldc    75", 
  129.   "sldc    76", 
  130.   "sldc    77", 
  131.   "sldc    78", 
  132.   "sldc    79", 
  133.   "sldc    80", 
  134.   "sldc    81", 
  135.   "sldc    82", 
  136.   "sldc    83", 
  137.   "sldc    84", 
  138.   "sldc    85", 
  139.   "sldc    86", 
  140.   "sldc    87", 
  141.   "sldc    88", 
  142.   "sldc    89", 
  143.   "sldc    90", 
  144.   "sldc    91", 
  145.   "sldc    92", 
  146.   "sldc    93", 
  147.   "sldc    94", 
  148.   "sldc    95", 
  149.   "sldc    96", 
  150.   "sldc    97", 
  151.   "sldc    98", 
  152.   "sldc    99", 
  153.   "sldc    100", 
  154.   "sldc    101", 
  155.   "sldc    102", 
  156.   "sldc    103", 
  157.   "sldc    104", 
  158.   "sldc    105", 
  159.   "sldc    106", 
  160.   "sldc    107", 
  161.   "sldc    108", 
  162.   "sldc    109", 
  163.   "sldc    110", 
  164.   "sldc    111", 
  165.   "sldc    112", 
  166.   "sldc    113", 
  167.   "sldc    114", 
  168.   "sldc    115", 
  169.   "sldc    116", 
  170.   "sldc    117", 
  171.   "sldc    118", 
  172.   "sldc    119", 
  173.   "sldc    120", 
  174.   "sldc    121", 
  175.   "sldc    122", 
  176.   "sldc    123", 
  177.   "sldc    124", 
  178.   "sldc    125", 
  179.   "sldc    126", 
  180.   "sldc    127", 
  181.   "abi        (absolute value integer)", 
  182.   "abr        (absolute value real)", 
  183.   "adi        (add integer)", 
  184.   "adr        (add real)", 
  185.   "land        (logical and)", 
  186.   "dif        (set difference)", 
  187.   "dvi        (divide integer)", 
  188.   "dvr        (divide real)", 
  189.   "chk        (check)", 
  190.   "flo        (float tos-1)", 
  191.   "flt        (float tos)", 
  192.   "inn        (set memberschip)", 
  193.   "int        (set intersection)", 
  194.   "lor        (logical or)", 
  195.   "modi        (modulo integer)", 
  196.   "mpi        (multiply integer)", 
  197.   "mpr        (multiply real)", 
  198.   "ngi        (negate integer)", 
  199.   "ngr        (negate real)", 
  200.   "lnot        (logical not)", 
  201.   "srs        (build subrange set)", 
  202.   "sbi        (substract integer)", 
  203.   "sbr        (substract real)", 
  204.   "sgs        (build singleton set)", 
  205.   "sqi        (square integer)", 
  206.   "sqr        (square real)", 
  207.   "sto        (store indirect word)", 
  208.   "ixs        (index string array)", 
  209.   "uni        (set union)", 
  210.   "lde    U,B    (load extended word)", 
  211.   "csp    Q    (call standard procedure)", 
  212.   "ldcn        (load constant nil)", 
  213.   "adj    U    (adjust set)", 
  214.   "fjp    J    (false jump)", 
  215.   "inc    B    (increment field pointer)", 
  216.   "ind    B    (load indirect word)", 
  217.   "ixa    B    (index array)", 
  218.   "lao    B    (load global address)", 
  219.   "lsa    Y    (load string address)", 
  220.   "lae    U,B    (load extended address)", 
  221.   "mov    B    (move words)", 
  222.   "ldo    B    (load global word)", 
  223.   "sas    U P    (string assign)", 
  224.   "sro    B    (store global word)", 
  225.   "xjp    R    (case jump)", 
  226.   "rnp    D    (return non-base procedure)", 
  227.   "cip    C    (call intermediate procedure)", 
  228.   "equ    T    (equal)", 
  229.   "geq    T    (greater or equal)", 
  230.   "grt    T    (greater)", 
  231.   "lda    D,B    (load intermediate address)", 
  232.   "ldc    X    (load multiple word constant)", 
  233.   "leq    T    (less or equal)", 
  234.   "les    T    (less than)", 
  235.   "lod    D,B    (load intermediate word)", 
  236.   "neq    T    (not equal)", 
  237.   "str    D,B    (store intermediate word)", 
  238.   "ujp    J    (unconditional jump)", 
  239.   "ldp        (load packed field)", 
  240.   "stp        (store into packed field)", 
  241.   "ldm    U    (load multiple words)", 
  242.   "stm    U    (store multiple words)", 
  243.   "ldb        (load byte)", 
  244.   "stb        (store byte)", 
  245.   "ixp    U,U    (index packed array)", 
  246.   "rbp    D    (return base procedure)", 
  247.   "cbp    C    (call base procedure)", 
  248.   "equi        (equal integer)", 
  249.   "geqi        (greater or equal integer)", 
  250.   "grti        (greater iteger)", 
  251.   "lla    B    (load local address)", 
  252.   "ldci    W    (load constant integer)", 
  253.   "leqi        (less or equal integer)", 
  254.   "lesi        (less than integer)", 
  255.   "ldl    B    (load local word)", 
  256.   "neqi        (not equal integer)", 
  257.   "stl    B    (store local word)", 
  258.   "cxp    A    (call external procedure)", 
  259.   "clp    C    (call local procedure)", 
  260.   "cgp    C    (call global procedure)", 
  261.   "lpa    Z    (load packed array)", 
  262.   "ste    U,B    (store extended word)", 
  263.   ".db    210", 
  264.   "efj    J    (equal false jump)", 
  265.   "nfj    J    (not equal false jump)", 
  266.   "bpt    B    (breakpoint)", 
  267.   "xit        (exit operating system)", 
  268.   "nop        (no operation)", 
  269.   "sldl    1    (short load local word)", 
  270.   "sldl    2    (short load local word)", 
  271.   "sldl    3    (short load local word)", 
  272.   "sldl    4    (short load local word)", 
  273.   "sldl    5    (short load local word)", 
  274.   "sldl    6    (short load local word)", 
  275.   "sldl    7    (short load local word)", 
  276.   "sldl    8    (short load local word)", 
  277.   "sldl    9    (short load local word)", 
  278.   "sldl    10    (short load local word)", 
  279.   "sldl    11    (short load local word)", 
  280.   "sldl    12    (short load local word)", 
  281.   "sldl    13    (short load local word)", 
  282.   "sldl    14    (short load local word)", 
  283.   "sldl    15    (short load local word)", 
  284.   "sldl    16    (short load local word)", 
  285.   "sldo    1    (short load global word)", 
  286.   "sldo    2    (short load global word)", 
  287.   "sldo    3    (short load global word)", 
  288.   "sldo    4    (short load global word)", 
  289.   "sldo    5    (short load global word)", 
  290.   "sldo    6    (short load global word)", 
  291.   "sldo    7    (short load global word)", 
  292.   "sldo    8    (short load global word)", 
  293.   "sldo    9    (short load global word)", 
  294.   "sldo    10    (short load global word)", 
  295.   "sldo    11    (short load global word)", 
  296.   "sldo    12    (short load global word)", 
  297.   "sldo    13    (short load global word)", 
  298.   "sldo    14    (short load global word)", 
  299.   "sldo    15    (short load global word)", 
  300.   "sldo    16    (short load global word)", 
  301.   "sind    0    (short load indirect word)", 
  302.   "sind    1    (short load indirect word)", 
  303.   "sind    2    (short load indirect word)", 
  304.   "sind    3    (short load indirect word)", 
  305.   "sind    4    (short load indirect word)", 
  306.   "sind    5    (short load indirect word)", 
  307.   "sind    6    (short load indirect word)", 
  308.   "sind    7    (short load indirect word)"
  309. };
  310.  
  311. static void PString(char *Buffer, word Addr)
  312. {
  313.   int    Len=MemRdByte(Addr,0);
  314.   int i;
  315.   *Buffer++='\'';
  316.   for (i=1; i<=Len; i++)
  317.     *Buffer++=MemRdByte(Addr,i);
  318.   *Buffer++='\'';
  319.   *Buffer++='\0';
  320. }
  321.  
  322. static word ReadStack(word Sp, int TosOffset)
  323. {
  324.   return(MemRdByte(Sp,2*TosOffset)+
  325.      (MemRdByte(Sp,2*TosOffset+1)<<8));
  326. }
  327.  
  328. static void ProcName(char *d, int Seg, int Proc, word Sp)
  329. {
  330.   if (Seg==0)
  331.     switch(Proc)
  332.       {
  333.       case 5:
  334.     sprintf(d, "Rewrite");
  335.     if (Sp)
  336.       {
  337.         d+=strlen(d);
  338.         *d++='(';
  339.         PString(d, ReadStack(Sp, 2));
  340.         d+=strlen(d);
  341.         *d++=')';
  342.         *d='\0';
  343.       }
  344.     break;
  345.       case 6:
  346.     sprintf(d, "Close");
  347.     break;
  348.       case 7:
  349.     sprintf(d, "Get");
  350.     break;
  351.       case 8:
  352.     sprintf(d, "Put");
  353.     break;
  354.       case 10:
  355.     sprintf(d, "Eof");
  356.     break;
  357.       case 11:
  358.     sprintf(d, "Eoln");
  359.     break;
  360.       case 12:
  361.     sprintf(d, "ReadInteger");
  362.     break;
  363.       case 13:
  364.     sprintf(d, "WriteInteger");
  365.     break;
  366.       case 16:
  367.     sprintf(d, "ReadChar");
  368.     break;
  369.       case 17:
  370.     sprintf(d, "WriteChar");
  371.     break;
  372.       case 18:
  373.     sprintf(d, "ReadString");
  374.     break;
  375.       case 19:
  376.     sprintf(d, "WriteString");
  377.     if (Sp)
  378.       {
  379.         d+=strlen(d);
  380.         *d++='(';
  381.         PString(d, ReadStack(Sp, 1));
  382.         d+=strlen(d);
  383.         *d++=')';
  384.         *d='\0';
  385.       }
  386.     break;
  387.       case 21:
  388.     sprintf(d,"ReadLn");
  389.     break;
  390.       case 22:
  391.     sprintf(d,"WriteLn");
  392.     break;
  393.       case 23:
  394.     sprintf(d,"Concat");
  395.     if (Sp)
  396.       {
  397.         d+=strlen(d);
  398.         *d++='(';
  399.         PString(d, ReadStack(Sp, 2));
  400.         d+=strlen(d);
  401.         *d++=',';
  402.         PString(d, ReadStack(Sp, 1));
  403.         d+=strlen(d);
  404.         *d++=')';
  405.         *d='\0';
  406.       }
  407.     break;
  408.       case 24:
  409.     sprintf(d,"Insert");
  410.     if (Sp)
  411.       {
  412.         d+=strlen(d);
  413.         *d++='(';
  414.         PString(d, ReadStack(Sp, 3));
  415.         d+=strlen(d);
  416.         *d++=',';
  417.         PString(d, ReadStack(Sp, 2));
  418.         d+=strlen(d);
  419.         sprintf(d, ", %d)", ReadStack(Sp, 0));
  420.       }
  421.     break;
  422.       case 25:
  423.     sprintf(d,"Copy");
  424.     if (Sp)
  425.       {
  426.         d+=strlen(d);
  427.         *d++='(';
  428.         PString(d, ReadStack(Sp, 3));
  429.         d+=strlen(d);
  430.         sprintf(d, ", %d, %d)",
  431.             ReadStack(Sp, 1),
  432.             ReadStack(Sp, 0));
  433.       }
  434.     break;
  435.       case 26:
  436.     sprintf(d,"Delete");
  437.     if (Sp)
  438.       {
  439.         d+=strlen(d);
  440.         *d++='(';
  441.         PString(d, ReadStack(Sp, 2));
  442.         d+=strlen(d);
  443.         sprintf(d, ", %d, %d)",
  444.             ReadStack(Sp, 1),
  445.             ReadStack(Sp, 0));
  446.       }
  447.     break;
  448.       case 27:
  449.     sprintf(d,"Pos");
  450.     if (Sp)
  451.       {
  452.         d+=strlen(d);
  453.         *d++='(';
  454.         PString(d, ReadStack(Sp, 3));
  455.         d+=strlen(d);
  456.         *d++=',';
  457.         PString(d, ReadStack(Sp, 2));
  458.         d+=strlen(d);
  459.         *d++=')';
  460.         *d='\0';
  461.       }
  462.     break;
  463.       case 28:
  464.     sprintf(d,"BlockRead/BlockWrite");
  465.     break;
  466.       case 29:
  467.     sprintf(d,"GotoXY");
  468.     if (Sp)
  469.       {
  470.         d+=strlen(d);
  471.         sprintf(d, "( %d, %d)",
  472.             ReadStack(Sp, 1),
  473.             ReadStack(Sp, 0));
  474.       }
  475.     break;
  476.       }
  477. }
  478.  
  479. word DisasmP(char *Buffer, word SegNo, word IpcBase, word Ipc, word JTab, word Sp)
  480. {
  481.   unsigned char OpCode=MemRdByte(IpcBase, Ipc++);
  482.   const char    *s=Instructions[OpCode];
  483.   char        *d=Buffer;
  484.   char        ch;
  485.   int        Val;
  486.  
  487.   while ((ch=*s++))
  488.     switch(ch)
  489.       {
  490.       case 'A':            /* CXP Arguments */
  491.     {
  492.       int Seg=MemRdByte(IpcBase, Ipc++);
  493.       int Proc=MemRdByte(IpcBase, Ipc++);
  494.       sprintf(d,"%d,%d ", Seg, Proc);
  495.       d +=strlen(d);
  496.       ProcName(d, Seg, Proc, Sp);
  497.       d +=strlen(d);
  498.     }
  499.     break;
  500.       case 'B':
  501.     Val=MemRdByte(IpcBase, Ipc++);
  502.     if (Val&0x80)
  503.       Val=((Val&0x7f)<<8)+MemRdByte(IpcBase, Ipc++);
  504.     sprintf(d,"%d", Val);
  505.     d +=strlen(d);
  506.     break;
  507.       case 'C':
  508.     Val=MemRdByte(IpcBase, Ipc++);
  509.     sprintf(d,"%d ", Val);
  510.     d +=strlen(d);
  511.     ProcName(d, SegNo, Val, Sp);
  512.     d +=strlen(d);
  513.     break;
  514.       case 'D':
  515.       case 'U':
  516.     Val=MemRdByte(IpcBase, Ipc++);
  517.     sprintf(d,"%d", Val);
  518.     d +=strlen(d);
  519.     break;
  520.       case 'P':
  521.     if (Sp)
  522.       {
  523.         PString(d, ReadStack(Sp, 0));
  524.         d +=strlen(d);
  525.       }
  526.     break;
  527.       case 'S':
  528.     Val=MemRdByte(IpcBase, Ipc++);
  529.     if (Val&0x80)
  530.       Val=-(0x100-Val);
  531.     sprintf(d,"%d", Val);
  532.     d +=strlen(d);
  533.     break;
  534.       case 'T':
  535.     Val=MemRdByte(IpcBase, Ipc++);
  536.     switch(Val)
  537.       {
  538.       case 2:
  539.         strcpy(d,"real");
  540.         break;
  541.       case 4:
  542.         strcpy(d,"string");
  543.         break;
  544.       case 6:
  545.         strcpy(d,"boolean");
  546.         break;
  547.       case 8:
  548.         strcpy(d,"set");
  549.         break;
  550.       case 10:
  551.         Val=MemRdByte(IpcBase, Ipc++);
  552.         if (Val&0x80)
  553.           Val=((Val&0x7f)<<8)+MemRdByte(IpcBase, Ipc++);
  554.         sprintf(d,"byte array, %d bytes", Val);
  555.         break;
  556.       case 12:
  557.         Val=MemRdByte(IpcBase, Ipc++);
  558.         if (Val&0x80)
  559.           Val=((Val&0x7f)<<8)+MemRdByte(IpcBase, Ipc++);
  560.         sprintf(d,"%d words", Val);
  561.         break;
  562.       default:
  563.         sprintf(d,"%d", Val);
  564.         break;
  565.       }
  566.     d +=strlen(d);
  567.     break;
  568.       case 'W':
  569.     Val=MemRdByte(IpcBase, Ipc++);
  570.     Val |= (MemRdByte(IpcBase, Ipc++))<<8;
  571.     sprintf(d,"%d", Val);
  572.     d +=strlen(d);
  573.     break;
  574.       case 'R':            /* case arguments */
  575.     {
  576.       int Min, Max, Default;
  577.       Ipc=(Ipc+1)&(~1);
  578.       Min=MemRdByte(IpcBase, Ipc++);
  579.       Min |= (MemRdByte(IpcBase, Ipc++))<<8;
  580.       Max=MemRdByte(IpcBase, Ipc++);
  581.       Max |= (MemRdByte(IpcBase, Ipc++))<<8;
  582.       Ipc++;
  583.       Default = MemRdByte(IpcBase, Ipc++);
  584.       if (Default&0x80)            /* kleiner null? */
  585.         {
  586.           Default=-(0x100-Default);
  587.           Default=-Default;
  588.           Default=(int)MemRdByte(JTab, -2)+
  589.         (MemRdByte(JTab, -1)<<8)+2-
  590.         ((int)MemRdByte(JTab, -Default)+
  591.          (MemRdByte(JTab, -Default+1)<<8)+Default);
  592.         }
  593.       else
  594.         Default=Ipc+Default;
  595.       sprintf(d,"%d,%d,%d  ", Min, Max, Default);
  596.       d +=strlen(d);
  597.       while (Min<Max+1)
  598.         {
  599.           Val=MemRdByte(IpcBase, Ipc++);
  600.           Val |= (MemRdByte(IpcBase, Ipc++))<<8;
  601.           sprintf(d,",%d", Ipc-2-Val);
  602.           d +=strlen(d);
  603.           Min++;
  604.         }
  605.     }
  606.     break;
  607.       case 'Q':
  608.     Val=MemRdByte(IpcBase, Ipc++);
  609.     switch(Val)
  610.       {
  611.       case 1:
  612.         strcpy(d, "new");
  613.         break;
  614.       case 2:
  615.         strcpy(d, "Moveleft");
  616.         break;
  617.       case 3:
  618.         strcpy(d, "Moveright");
  619.         break;
  620.       case 4:
  621.         strcpy(d, "exit");
  622.         break;
  623.       case 5:
  624.         strcpy(d, "unitread");
  625.         break;
  626.       case 6:
  627.         strcpy(d, "unitwrite");
  628.         break;
  629.       case 7:
  630.         strcpy(d, "idsearch");
  631.         break;
  632.       case 8:
  633.         strcpy(d, "treesearch");
  634.         break;
  635.       case 9:
  636.         strcpy(d, "time");
  637.         break;
  638.       case 10:
  639.         strcpy(d, "fillchar");
  640.         break;
  641.       case 11:
  642.         sprintf(d, "scan");
  643.         break;
  644.       case 12:
  645.         strcpy(d, "unitstat");
  646.         break;
  647.       case 21:
  648.         strcpy(d, "load_segment");
  649.         break;
  650.       case 22:
  651.         strcpy(d, "unload_segment");
  652.         break;
  653.       case 32:
  654.         strcpy(d, "mark");
  655.         break;
  656.       case 33:
  657.         strcpy(d, "release");
  658.         break;
  659.       case 34:
  660.         strcpy(d, "ioresult");
  661.         break;
  662.       case 35:
  663.         strcpy(d, "unitbusy");
  664.         break;
  665.       case 37:
  666.         strcpy(d, "unitwait");
  667.         break;
  668.       case 38:
  669.         strcpy(d, "unitclear");
  670.         break;
  671.       case 39:
  672.         strcpy(d, "halt");
  673.         break;
  674.       case 40:
  675.         strcpy(d, "memavail");
  676.         break;
  677.       default:
  678.         sprintf(d,"%d", Val);
  679.         break;
  680.       }
  681.     d +=strlen(d);
  682.     break;
  683.       case 'J':
  684.     Val=MemRdByte(IpcBase, Ipc++);
  685.     if (Val&0x80)            /* kleiner null? */
  686.       {
  687.         Val=-(0x100-Val);
  688.         Val=-Val;
  689.  
  690.         Val=(int)MemRdByte(JTab, -2)+
  691.           (MemRdByte(JTab, -1)<<8)+2-
  692.           ((int)MemRdByte(JTab, -Val)+
  693.            (MemRdByte(JTab, -Val+1)<<8)+Val);
  694.       }
  695.     else
  696.       {
  697.         Val=Ipc+Val;
  698.       }
  699.     sprintf(d,"%d", Val);
  700.     d +=strlen(d);
  701.     break;
  702.       case 'V':
  703.     *d='\0';
  704.     d +=strlen(d);
  705.     break;
  706.       case 'X':
  707.     Val=MemRdByte(IpcBase, Ipc++);
  708.     sprintf(d,"%d", Val);
  709.     d +=strlen(d);
  710.     Ipc=(Ipc+1)&~1;
  711.     while (Val--)
  712.       {
  713.         word w;
  714.         w=MemRdByte(IpcBase,Ipc)+(MemRdByte(IpcBase,Ipc+1)<<8);
  715.         Ipc += 2;
  716.         sprintf(d,",%04x", w);
  717.         d +=strlen(d);
  718.       }
  719.     break;
  720.       case 'Y':
  721.     Val=MemRdByte(IpcBase, Ipc++);
  722.     sprintf(d,"%d,'", Val);
  723.     d +=strlen(d);
  724.     while (Val--)
  725.       *d++=MemRdByte(IpcBase, Ipc++);
  726.     *d++='\'';
  727.     break;
  728.       case 'Z':
  729.     Val=MemRdByte(IpcBase, Ipc++);
  730.     sprintf(d,"%d", Val);
  731.     d +=strlen(d);
  732.     Ipc=(Ipc+1)&~1;
  733.     while (Val--)
  734.       {
  735.         sprintf(d,",%02x", MemRdByte(IpcBase,Ipc));
  736.         Ipc ++;
  737.         d +=strlen(d);
  738.       }
  739.     break;
  740.  
  741.       default:
  742.     *d++=ch;
  743.       }
  744.   *d++='\0';
  745.   return(Ipc);
  746. }
  747.  
  748. void PrintStack(char *Buffer, word Sp)
  749. {
  750.   char    *p=Buffer;
  751.   *p='\0';
  752.   while (Sp<0x200)
  753.     {
  754.       sprintf(p," %04x",MemRd(Sp));
  755.       p+=strlen(p);
  756.       Sp+=2;
  757.     }
  758. }
  759.  
  760. void PrintStaticChain(char *Buffer, word Mp)
  761. {
  762.   char    *p=Buffer;
  763.   *p='\0';
  764.   while (1)
  765.     {
  766.       word NextMp;
  767.       sprintf(p," %04x",Mp);
  768.       p+=strlen(p);
  769.       NextMp=MemRd(Mp);
  770.       if (!NextMp || (Mp==NextMp))
  771.     break;
  772.       Mp=NextMp;
  773.     }
  774. }
  775.